﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using System.Diagnostics;
using LensflareAIContest;

namespace LensflareAIContest {
    public class AIHoldPosition : AI {
        Dictionary<int, Vector2> targetPositions;
        Random random = new Random();

        public override void TimeElapsed(float secondsSinceLastTick, float secondsTotal) {
            
        }

        public override Vector2 ThrustForUnit(int index) {
            var myUnits = Info.UnitsInfoForTeamIndex(TeamIndex);

            //set initial target position for each unit:
            if (targetPositions == null) {
                targetPositions = new Dictionary<int, Vector2>();
                foreach (var unit in myUnits) {
                    var randomVector = new Vector2((float)random.NextDouble() * 2.0f - 1.0f, (float)random.NextDouble() * 2.0f - 1.0f);
                    randomVector.X *= 0; //Info.Rules.World.Extent.X * 0.5f;
                    randomVector.Y *= Info.Rules.World.Extent.Y * 0.5f;
                    targetPositions.Add(unit.ID, randomVector);
                }
            }

            float decelerationFactor = 50;
            var currentUnit = myUnits[index];

            Vector2 targetPosition;
            bool gotValue = targetPositions.TryGetValue(currentUnit.ID, out targetPosition);
            if (gotValue) {
                var distanceToTarget = targetPosition - currentUnit.Position;
                var thrust = distanceToTarget - currentUnit.Velocity * decelerationFactor;
                return thrust;
            } else {
                return new Vector2(0, 0);
            }
        }

        public override Vector2? PreparedShotForUnit(int index) {
            var myUnits = Info.UnitsInfoForTeamIndex(TeamIndex);
            var enemyUnits = Info.UnitsInfoForTeamIndex(EnemyTeamIndex);
            Debug.Assert(myUnits != null && enemyUnits != null);

            bool enemyHasUnits = enemyUnits.Length > 0;

            if (enemyHasUnits) {
                //find the closest enemy unit...
                float minDistToEnemyUnit = float.PositiveInfinity;
                int indexOfUnitWithMinDist = -1;
                Vector2 posOfMyCurrentUnit = myUnits[index].Position;
                for (int enemyUnitIndex = 0; enemyUnitIndex < enemyUnits.Length; ++enemyUnitIndex) {
                    UnitInfo enemyUnit = enemyUnits[enemyUnitIndex];
                    float dist = (posOfMyCurrentUnit - enemyUnit.Position).LengthSquared();
                    if (dist < minDistToEnemyUnit) {
                        minDistToEnemyUnit = dist;
                        indexOfUnitWithMinDist = enemyUnitIndex;
                    }
                }

                //... and shoot at it:
                if (indexOfUnitWithMinDist >= 0) {
                    Vector2 direction = enemyUnits[indexOfUnitWithMinDist].Position - posOfMyCurrentUnit;
                    return direction;
                } else {
                    return null;
                }
            } else {
                //shoot at the enemy heart:
                var enemyHeart = Info.HeartInfoForTeamIndex(EnemyTeamIndex);
                if (enemyHeart != null) {
                    if (enemyHeart.Health > 0) {
                        Vector2 posOfMyCurrentUnit = myUnits[index].Position;
                        Vector2 direction = enemyHeart.Position - posOfMyCurrentUnit;
                        return direction;
                    } else {
                        return null; //it's dead. let it rest in peace.
                    }
                } else {
                    return null;
                }
            }
        }

        public override String GetName() {
            return "Hold Position 1.0";
        }
    }
}
